From e8a1d15316580a6e65b43ad7c40ef748560e3a29 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 18 Jul 2011 10:21:18 -0700 Subject: [PATCH] * fileio.c (Fcopy_file): Adjust mode if fchown fails. (Bug#9002) If fchown fails to set both uid and gid, try to set just gid, as that is sometimes allowed. Adjust the file's mode to eliminate setuid or setgid bits that are inappropriate if fchown fails. --- src/ChangeLog | 7 +++++++ src/fileio.c | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 7809f221c3c..67dde81eb46 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2011-07-18 Paul Eggert + + * fileio.c (Fcopy_file): Adjust mode if fchown fails. (Bug#9002) + If fchown fails to set both uid and gid, try to set just gid, + as that is sometimes allowed. Adjust the file's mode to eliminate + setuid or setgid bits that are inappropriate if fchown fails. + 2011-07-18 Stefan Monnier * xdisp.c (next_element_from_string, next_element_from_buffer): Use EQ diff --git a/src/fileio.c b/src/fileio.c index a52e834c2b2..fb2c081ae5c 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -38,8 +38,6 @@ along with GNU Emacs. If not, see . */ #include #endif -#include - #include "lisp.h" #include "intervals.h" #include "buffer.h" @@ -1961,9 +1959,21 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) owner and group. */ if (input_file_statable_p) { + int mode_mask = 07777; if (!NILP (preserve_uid_gid)) - ignore_value (fchown (ofd, st.st_uid, st.st_gid)); - if (fchmod (ofd, st.st_mode & 07777) != 0) + { + /* Attempt to change owner and group. If that doesn't work + attempt to change just the group, as that is sometimes allowed. + Adjust the mode mask to eliminate setuid or setgid bits + that are inappropriate if the owner and group are wrong. */ + if (fchown (ofd, st.st_uid, st.st_gid) != 0) + { + mode_mask &= ~06000; + if (fchown (ofd, -1, st.st_gid) == 0) + mode_mask |= 02000; + } + } + if (fchmod (ofd, st.st_mode & mode_mask) != 0) report_file_error ("Doing chmod", Fcons (newname, Qnil)); } #endif /* not MSDOS */ -- 2.30.2